package com.wkbb.sports.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wkbb.common.base.BaseServiceImpl;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.sports.dto.*;
import com.wkbb.sports.enums.SportsRuleTypeEnum;
import com.wkbb.sports.mapper.*;
import com.wkbb.sports.model.*;
import com.wkbb.sports.service.ExamineService;

import com.wkbb.sports.utils.SportsUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
@Slf4j
public class ExamineServiceImpl extends BaseServiceImpl<HlifeExamine> implements ExamineService {

    @Autowired
    private HlifeExamineMapper hlifeExamineMapper;

    @Autowired
    private HlifeExamineRuleMapper hlifeExamineRuleMapper;

    @Autowired
    private HlifeExamineRuleItemMapper hlifeExamineRuleItemMapper;

    @Autowired
    private HlifeExamineRulePlusesMapper hlifeExamineRulePlusesMapper;

    @Autowired
    private HlifeAchievementMapper achievementMapper;

    public void setMapper(HlifeExamineMapper mapper) {
        super.setMapper(mapper);
    }


    /**
     * 分页条件查询
     * @param params
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<ExamineDto> getExaminePageList(Map<String, Object> params, Integer pageNo, Integer pageSize) {
        if (pageNo == null || pageSize == null) {
            return null;
        }
        //查询条件不为空时,查询符合条件的项目id
        if (!StringUtils.isEmpty(params.get("gradeId")) || !StringUtils.isEmpty(params.get("sex"))) {
            HashSet<Long> examineIds = new HashSet<>();
            List<HlifeExamineRule> rules = hlifeExamineRuleMapper.getListByMapParams(params);
            if (rules != null && rules.size() > 0) {
                for (HlifeExamineRule rule : rules) {
                    examineIds.add(rule.getExaminationId());
                }
                params.put("examineIds", examineIds);
            } else {                                      //没有数据
                return new PageInfo<ExamineDto>();
            }
        }

        Page<ExamineDto> page = PageHelper.startPage(pageNo, pageSize, true);
        List<ExamineDto> examinePageList = hlifeExamineMapper.getExaminePageList(params);
        for (int i = 0; i < examinePageList.size(); i++) {
            //年级列表
            List<ExamineRuleDto> ruleDtoList = new ArrayList<>();
            ExamineDto examineDto = examinePageList.get(i);
            params.put("examinationId", examineDto.getId());
            //查询体检项目对应的年级规则
            List<HlifeExamineRule> ruleList = hlifeExamineRuleMapper.getListByMapParams(params);
            for (HlifeExamineRule rule : ruleList) {
                List<ExamineRuleItemDto> itemDtoList = new ArrayList<>();
                ExamineRuleDto rules = new ExamineRuleDto();
                rules.setId(rule.getId());
                rules.setRuleType(rule.getRuleType());              //排序规则
                rules.setGradeId(rule.getGradeId());                //年级id
                rules.setSex(rule.getSex());                        //性别
                rules.setGradeName(rule.getGradeName());            //年级名称
                rules.setExaminationId(rule.getExaminationId());    //体检项目id
                params.put("ruleId", rule.getId());
                List<HlifeExamineRuleItem> itemList = hlifeExamineRuleItemMapper.getListByMapParams(params);
                //规则列表
                for (HlifeExamineRuleItem item : itemList) {
                    ExamineRuleItemDto itemDto = new ExamineRuleItemDto();        //体检规则
                    itemDto.setMax(item.getMax());                                //最大值
                    itemDto.setComment(item.getComment());                        //评语
                    itemDto.setName(item.getName());                              //规则名称
                    itemDto.setScore(item.getScore());                            //成绩
                    itemDto.setScoreValue(item.getScoreValue());
                    itemDto.setRuleId(item.getRuleId());    //年级规则id
                    itemDto.setMin(item.getMin());                                //最小值
                    itemDtoList.add(itemDto);
                    rules.setRuleItemList(itemDtoList);
                }
                ruleDtoList.add(rules);
            }
            examineDto.setRuleList(ruleDtoList);
        }
        PageInfo<ExamineDto> pageInfo = new PageInfo<ExamineDto>(examinePageList);
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }
    /**
     * 增加项目名
     *
     * @param examineDto 参数列表
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
	public  ResultDTO<?> addExamine(ExamineDto examineDto) {

    	//StringBuffer sb = new StringBuffer();

		Map<String, Object> params = new HashMap<>();
        params.put("orgId", examineDto.getOrgId());
        params.put("name", examineDto.getName());
        //检查名字唯一
        HlifeExamine examine = hlifeExamineMapper.checkExamineName(params);
        if (examine != null) {                  //名字唯一返回错误
            return new ResultDTO<>(ErrorCode.AREA_TEMPLATE_EXIST);
        }
        
        HlifeExamine exam = new HlifeExamine();
        exam.setOrgId(examineDto.getOrgId());
        exam.setName(examineDto.getName());                         //项目名称
        exam.setRemark(examineDto.getRemark());                     //项目内容
        exam.setUnit(examineDto.getUnit());                         //项目单位
        exam.setReadStatus((byte) 0);                               //是否只读
        
        logout("exam(org:" + exam.getOrgId() + ", name:" + exam.getName() + ", unit:" + exam.getUnit() + ")");
        
        //插入项目信息
        hlifeExamineMapper.insert(exam);
        
        insertRules(examineDto.getRuleList(), exam);
        
        //log.info(sb.toString());
        
		return new ResultDTO<>(true);
	}


    protected void insertRules(List<ExamineRuleDto> rules, HlifeExamine exam) {
    	
    	String unit = exam.getUnit();
    	
		for (ExamineRuleDto ruleDto : rules) {
        	
        	HlifeExamineRule rule = new HlifeExamineRule();
        	rule.setExaminationId(exam.getId());
        	rule.setOrgId(exam.getOrgId());
        	rule.setGradeId(ruleDto.getGradeId());           //年级id
        	rule.setGradeName(ruleDto.getGradeName());       //年级名称
        	rule.setSex(ruleDto.getSex());                   //性别
        	rule.setRuleType(ruleDto.getRuleType());         //排序规则
        	rule.setWeight(ruleDto.getWeight());
        	
        	logout("  rule(grade:" + rule.getGradeId() + ", sex:" + rule.getSex() + ", ruleType:" + rule.getRuleType() + ", weight:" + rule.getWeight() + ")");
        	
        	hlifeExamineRuleMapper.insert(rule);
        	
        	//体检规则列表
            List<ExamineRuleItemDto> itemsDtos = ruleDto.getRuleItemList();
            if (itemsDtos == null || itemsDtos.size() <= 0) {
            	continue;
            }

            
            double base = rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue() ? 99999D : 0;
        	
        	Double baseMax = null;
        	
            String link = rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue() ? " > n >= " : " >= n > ";
        	
            for (ExamineRuleItemDto itemDto : itemsDtos) {
            	HlifeExamineRuleItem item = new HlifeExamineRuleItem();
                item.setRuleId(rule.getId());
                item.setScore(itemDto.getScore());                  //分数
                item.setScoreValue(itemDto.getScoreValue());
                item.setName(itemDto.getName());                    //级别名称
                item.setComment(itemDto.getComment());              //评论
                item.setStatus((byte)1);
                double value = SportsUtils.translate(unit, itemDto.getScoreValue());
                if(baseMax == null) {
                	baseMax = value;
                }
                if (rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue()) {
                	item.setMax(base);
                	item.setMin(value);
                	base = value;
                }else {
                	item.setMax(value);
                	item.setMin(base);
                	base = value;
                }
                logout("   item(" + item.getScoreValue() + ") " + item.getMax() + link + item.getMin() + " : " + item.getScore());

                if (item.getMax() < item.getMin()) {                  //max < min
                    throw new RuntimeException(item.getMax() + link + item.getMin());
                }
                
                hlifeExamineRuleItemMapper.insert(item);
            }
            
            List<ExamineRulePlusesDto> pluses = ruleDto.getPlusesList();
            if (pluses == null || pluses.size() <= 0) {
            	continue;
            }
            
            logout("baseMax:" + baseMax);
            
            base = rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue() ? 99999D : 0;
        	
            for (ExamineRulePlusesDto plusDto : pluses) {
            	
            	String bonusValue = plusDto.getBonusValue();
            	
            	if(bonusValue == null || "".equals(bonusValue)) {
            		continue;
            	}
            	
                HlifeExamineRulePluses plus = new HlifeExamineRulePluses();
                plus.setRuleId(rule.getId());
                plus.setBonusValue(bonusValue);                              //额外成绩
                plus.setScore(plusDto.getScore());                           //额外分数
                
                bonusValue = bonusValue.replace("+", "").replace("-", "");
                double value = SportsUtils.translate(unit, bonusValue);
                if (rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue()) {
                	value = baseMax + value;
                	plus.setMax(base);
                	plus.setMin(value);
                	base = value;
                }else {
                	value = baseMax - value;
                	plus.setMax(value);
                	plus.setMin(base);
                	base = value;
                }
                logout("   plus(" + plus.getBonusValue() + ") " + plus.getMax() + link + plus.getMin() + " : " + plus.getScore());

                if (plus.getMax() < plus.getMin()) {                  //max < min
                	throw new RuntimeException(plus.getMax() + link + plus.getMin());
                }
                hlifeExamineRulePlusesMapper.insert(plus);
            }
        }
	}
    /**
     * 删除体检项目
     * @param params
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultDTO<?> delExamine(Map<String, Object> params) throws Exception {
        try {
            HlifeExamine examine = hlifeExamineMapper.getByMapParams(params);
            if (examine.getReadStatus() == 1) {
                return new ResultDTO<>(false, "200", "只读不能删除");
            }
            params.put("type", "1");                                                //type代表考试类型
            List<HlifeAchievement> achievements = achievementMapper.getAchivementByProjectId(params);
            //没有考试成绩可以删除
            if (achievements == null || achievements.size() == 0) {
                List<HlifeExamineRule> ruleList = hlifeExamineRuleMapper.getListByMapParams(params);
                if (ruleList != null && ruleList.size() > 0) {
                    hlifeExamineRuleItemMapper.delExmine(ruleList);
                }
                hlifeExamineRuleMapper.delExmine(params);
                hlifeExamineMapper.delExmine(params);
                return new ResultDTO<>(true);
            } else {
                return new ResultDTO<>(false, "200", "项目已有分数不能删除");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception();
        }
    }


    /**
     * 详细信息
     * @param params
     * @return
     */
    @Override
    public List<ExamineDto> getExamineById(Map<String, Object> params) {
        List<ExamineDto> examineDtoList = hlifeExamineMapper.getExamineById(params);
        for (int i = 0; i < examineDtoList.size(); i++) {
            //年级列表
            List<ExamineRuleDto> ruleDtoList = new ArrayList<>();
            ExamineDto examineDto = examineDtoList.get(i);
            params.put("examinationId", examineDto.getId());
            //查询体检项目对应的年级规则
            List<HlifeExamineRule> ruleList = hlifeExamineRuleMapper.getListByMapParams(params);
            for (HlifeExamineRule rule : ruleList) {
                List<ExamineRuleItemDto> itemDtoList = new ArrayList<>();
                ExamineRuleDto rules = new ExamineRuleDto();
                rules.setId(rule.getId());
                rules.setRuleType(rule.getRuleType());              //排序规则
                rules.setWeight(rule.getWeight());
                rules.setGradeId(rule.getGradeId());                //年级id
                rules.setSex(rule.getSex());                        //性别
                rules.setGradeName(rule.getGradeName());            //年级名称
                rules.setExaminationId(rule.getExaminationId());    //体检项目id
                params.put("ruleId", rule.getId());
                List<HlifeExamineRuleItem> itemList = hlifeExamineRuleItemMapper.getListByMapParams(params);
                //规则列表
                for (HlifeExamineRuleItem item : itemList) {
                    ExamineRuleItemDto itemDto = new ExamineRuleItemDto();        //体检规则
                    itemDto.setMax(item.getMax());                                //最大值
                    itemDto.setComment(item.getComment());                        //评语
                    itemDto.setName(item.getName());                              //规则名称
                    itemDto.setScore(item.getScore());                            //成绩
                    itemDto.setScoreValue(item.getScoreValue());
                    itemDto.setRuleId(item.getRuleId());    //年级规则id
                    itemDto.setMin(item.getMin());                                //最小值
                    itemDtoList.add(itemDto);
                    rules.setRuleItemList(itemDtoList);
                }
                /**
                 * 额外加分
                 */
                List<ExamineRulePlusesDto> plusesDtList = new ArrayList<>();
                List<HlifeExamineRulePluses> plusesList = hlifeExamineRulePlusesMapper.getListByMapParams(params);
                for (HlifeExamineRulePluses rulePluses : plusesList) { //去掉最后一个区间
                    ExamineRulePlusesDto pluses = new ExamineRulePlusesDto();
                    pluses.setMin(rulePluses.getMin());
                    pluses.setMax(rulePluses.getMax());
                    pluses.setBonusValue(rulePluses.getBonusValue());
                    pluses.setScore(rulePluses.getScore());
                    pluses.setRuleId(rulePluses.getRuleId());
                    plusesDtList.add(pluses);
                    rules.setPlusesList(plusesDtList);
                }
                ruleDtoList.add(rules);
            }
            examineDto.setRuleList(ruleDtoList);
        }
        return examineDtoList;
    }

    /**
     * 修改体检信息
     * @param examineDto
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultDTO<?> updateExamine(ExamineDto examineDto) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("orgId", examineDto.getOrgId());
        params.put("id", examineDto.getId());
        //检查提交的是否是同一个项目名称
        HlifeExamine hlifeExamine = hlifeExamineMapper.getByMapParams(params);
        if (hlifeExamine.getId().longValue() == examineDto.getId().longValue()) {
            //只读只可以修改年级
            if (hlifeExamine.getReadStatus() == 1) {
                for (ExamineRuleDto examineRuleDto : examineDto.getRuleList()) {
                    if (examineRuleDto.getId() == null || "".equals(examineRuleDto.getId())) {
                        log.info("规年级则id : 为null");
                        return new ResultDTO<>(false, "200", "参数缺失");
                    }
                    HlifeExamineRule rule = new HlifeExamineRule();
                    rule.setGradeName(examineRuleDto.getGradeName());
                    rule.setGradeId(examineRuleDto.getGradeId());
                    rule.setId(examineRuleDto.getId());
                    hlifeExamineRuleMapper.update(rule);                     //更新年级
                }
                return new ResultDTO<>(true);
            }
            Map<String, Object> param = new HashMap<>();
            param.put("orgId", examineDto.getOrgId());
            param.put("name", examineDto.getName());
            param.put("checkId", examineDto.getId());
            //检查名字唯一
            HlifeExamine checkExamineName = checkExamineName(param);
            if (checkExamineName != null) {                                 //名字唯一返回错误
                return new ResultDTO<>(false, "200", "体检项目名已存在");
            }
            params.put("examineId", examineDto.getId());
            HlifeExamine examine = new HlifeExamine();
            examine.setId(examineDto.getId());
            examine.setUnit(examineDto.getUnit());
            examine.setName(examineDto.getName());
            examine.setOrgId(examineDto.getOrgId());
            examine.setUpdateUser(examineDto.getUpdateUser());
            examine.setRemark(examineDto.getRemark());
            hlifeExamineMapper.update(examine);
            //删除年级规则和得分规则
            List<HlifeExamineRule> rulesList = hlifeExamineRuleMapper.getListByMapParams(params);
            if (rulesList != null && rulesList.size() > 0) {
                hlifeExamineRuleItemMapper.delExmine(rulesList);
            }
            hlifeExamineRuleMapper.delExmine(params);

            //年级规则列表
            insertRules(examineDto.getRuleList(), examine);
        } else {
            return new ResultDTO<>(ErrorCode.AREA_TEMPLATE_EXIST);
        }
        return new ResultDTO<>(true);
    }

    /**
     * 检查名称重复
     * @return
     */
    public HlifeExamine checkExamineName(Map<String, Object> params) {
        return hlifeExamineMapper.checkExamineName(params);
    }

    @Override
    public void copyRule(long sourceOrg, long sourceGrade, long targetOrg, long targetGrade) throws Exception {
        List<HlifeExamine> exams = hlifeExamineMapper.getExamineListByOrg(sourceOrg);

        Date now = new Date();

        if (exams == null) {
            logout("not found any exam, org:" + sourceOrg);
            return;
        }

        for (HlifeExamine exam : exams) {
            exam.setOrgId(targetOrg);
            exam.setCreateTime(now);
            exam.setUpdateTime(now);

            exam.setReadStatus((byte) 1);

            logout("copy exam:" + exam.getId());

            hlifeExamineMapper.insert(exam);

            long examId = exam.getId();

            List<HlifeExamineRule> rules = hlifeExamineRuleMapper.getExamineRuleListByExamGrade(examId, sourceGrade);

            if (rules == null || rules.size() <= 0) {
                logout(" not found any rule(grade:" + sourceGrade + ")");
                continue;
            }

            for (HlifeExamineRule rule : rules) {
                rule.setExaminationId(examId);
                rule.setOrgId(targetOrg);
                rule.setGradeId(targetGrade);
                rule.setCreateTime(now);
                rule.setUpdateTime(now);

                logout(" copy rule(id:" + rule.getId() + ", grade:" + sourceGrade + ")");

                hlifeExamineRuleMapper.insert(rule);

                Long ruleId = rule.getId();

                List<HlifeExamineRuleItem> items = hlifeExamineRuleItemMapper.getItemListByRule(ruleId);

                if (items != null && items.size() > 0) {
                    for (HlifeExamineRuleItem item : items) {
                        item.setRuleId(ruleId);
                        item.setCreateTime(now);
                        item.setUpdateTime(now);
                        hlifeExamineRuleItemMapper.insert(item);
                    }
                    logout("  copy " + items.size() + " item(s)");
                } else {
                    logout("  not found any item");
                }

                List<HlifeExamineRulePluses> pluses = hlifeExamineRulePlusesMapper.getPlusListByRule(ruleId);

                if (pluses != null && pluses.size() > 0) {
                    for (HlifeExamineRulePluses plus : pluses) {
                        plus.setRuleId(ruleId);
                        plus.setCreateTime(now);
                        plus.setUpdateTime(now);
                        hlifeExamineRulePlusesMapper.insert(plus);
                    }
                    logout("  copy " + pluses.size() + " plus(s)");
                } else {
                    logout("  not found any plus");
                }
            }
        }
        //System.out.println(sb.toString());
        //sb.setLength(0);
    }

    private void logout(String msg) {
        //System.out.println(msg);
        //sb.append(msg).append("\n");
        log.info(msg);
    }
}